﻿using System.Collections.Generic;
using System.Linq.Expressions;

using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where.Call;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where.Comparison;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where.Logical;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where.Members;

namespace Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Where
{
    /// <summary>
    ///
    /// </summary>
    internal class WhereExpressionHandler
    {
        private readonly IList<IWhereExpressionHandler> _expressions = new List<IWhereExpressionHandler>();

        /// <summary>
        ///
        /// </summary>
        public WhereExpressionHandler()
        {
            Add(new AndAlsoWhereExpressionHandler());
            Add(new OrElseWhereExpressionHandler());

            Add(new EqualWhereExpressionHandler());
            Add(new GreaterThanOrEqualWhereExpressionHandler());
            Add(new GreaterThanWhereExpressionHandler());
            Add(new LessThanOrEqualWhereExpressionHandler());
            Add(new LessThanWhereExpressionHandler());
            Add(new NotEqualWhereExpressionHandler());

            Add(new CallValueExpressionHandlerHandler());
            Add(new MemberAccessExpressionHandler());
            Add(new MemberAccessNotExpressionHandler());
        }

        /// <summary>
        ///
        /// </summary>
        public static WhereExpressionHandler Instance = new();

        /// <summary>
        ///
        /// </summary>
        /// <param name="whereExpression"></param>
        public void Add(IWhereExpressionHandler whereExpression)
        {
            if (whereExpression != null)
                _expressions.Add(whereExpression);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public WhereExpressionResult Execute(ExpressionContext context, Expression expression)
        {
            if (expression != null)
            {
                foreach (var whereExpression in _expressions)
                {
                    if (whereExpression.GetExpressionType() == expression.NodeType)
                    {
                        var result = whereExpression.Execute(context, expression);

                        if (result.Status)
                            return result;
                    }
                }
            }

            return new WhereExpressionResult();
        }
    }
}